import os
from django.db import models
from django.conf import settings
from django.utils import timezone
from docx.shared import Pt, RGBColor
from backend.tools import *
from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT


class Settings(models.Model):
    StartTime = models.DateTimeField(blank=True, null=True)    # 开始时间(null)
    DeadLine = models.DateTimeField(blank=True, null=True)     # 结束时间(null)
    AnswerTime = models.IntegerField(blank=True, null=True)    # 用户作答时间 单位 秒(null)
    IPLimit = models.BooleanField(blank=True, default=False)   # IP限制(False)
    Login = models.BooleanField(blank=True, default=False)     # 是否登录后才能回答(False)

    Times = models.IntegerField(blank=True, null=True)         # 回答限额(报名问卷)(null)
    Reorder = models.BooleanField(blank=True, null=True)       # 是否对题目进行乱序(考试问卷)(null)

    def to_dict(self, fields=None, exclude=None):
        return get_dict(self, fields, exclude)

    def export(self, doc, type):
        p = doc.add_paragraph()
        p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
        p.paragraph_format.space_before = Pt(8)
        p.paragraph_format.space_after = Pt(8)
        if self.StartTime:
            r = p.add_run('开始时间: ' + self.StartTime.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            r = p.add_run('开始时间: 未设置    ')
        r.font.size = Pt(9)
        if self.DeadLine:
            r = p.add_run('结束时间: ' + self.DeadLine.strftime('%Y-%m-%d %H:%M:%S'))
        else:
            r = p.add_run('结束时间: 未设置    ')
        r.font.size = Pt(9)
        if self.AnswerTime:
            sec = self.AnswerTime
            minute = int(sec / 60 + 0.5)
            hour = int(minute / 60 + 0.5)
            sec = sec % 60
            minute = minute % 60
            r = p.add_run('作答时长: ' + str(hour) + '小时' + str(minute) + '分' + str(sec) + '秒')
            r.font.size = Pt(9)
        r.add_break()
        if self.IPLimit:
            r = p.add_run('同一IP可答题次数: 一次    ')
        else:
            r = p.add_run('同一IP可答题次数: 无限制    ')
        r.font.size = Pt(9)
        if self.Login:
            r = p.add_run('是否要求登录后作答: 是    ')
        else:
            r = p.add_run('是否要求登录后作答: 否    ')
        r.font.size = Pt(9)
        r.add_break()
        if type == 3 and self.Times:
            r = p.add_run('限填份数: ' + str(self.Times) + '份    ')
            r.font.size = Pt(9)
        if type == 4:
            if self.Reorder:
                r = p.add_run('考试问卷题目是否乱序显示: 是    ')
            else:
                r = p.add_run('考试问卷题目是否乱序显示: 否    ')
            r.font.size = Pt(9)


def getDefaultSettings():
    se = Settings()
    se.save()
    return se


class Questionnaire(models.Model):
    CreateUser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='Questionnaire')
    CreateTime = models.DateTimeField(blank=True, null=True)
    UpdateTime = models.DateTimeField(blank=True, null=True)
    ReleaseTime = models.DateTimeField(blank=True, null=True)
    Open = models.BooleanField(blank=True, default=False)
    Text = models.TextField(blank=True, null=True)
    Title = models.TextField(blank=True, null=True)
    EncodeID = models.TextField(blank=True, null=True)
    Star = models.BooleanField(blank=True, default=False)
    Remove = models.BooleanField(blank=True, default=False)
    ShowNumber = models.BooleanField(blank=True, default=True)
    Type = models.IntegerField(choices=((1, '普通问卷'), (2, '投票问卷'), (3, '报名问卷'), (4, '考试问卷'), (5, '疫情打卡问卷')), blank=True, default=1)
    Settings = models.ForeignKey(Settings, on_delete=models.SET_DEFAULT, default=getDefaultSettings, blank=True)

    def to_dict(self, fields=None, exclude=None):
        checkQuestionnaireTime(self)
        data = get_dict(self, fields, exclude)
        data['CreateUser'] = self.CreateUser.username
        data["Question"] = []
        for q in self.Question.all():
            data["Question"].append(q.to_dict())
        sFields = ['StartTime', 'DeadLine', 'AnswerTime', 'IPLimit', 'Login', ]
        if self.Type == 2:
            sFields.append('ShowResultBeforeVote')
        if self.Type == 3:
            sFields.append('Times')
        if self.Type == 4:
            sFields.append('Reorder')
        setting = self.Settings.to_dict(fields=sFields)
        data["Settings"] = setting
        if exclude:
            for ex in exclude:
                if ex in data:
                    del data[ex]
        if fields:
            for key in data:
                if key not in fields:
                    del data[key]
        return data

    def to_copy(self):
        checkQuestionnaireTime(self)
        data = get_dict(self,  exclude=['id', 'CreateTime', 'UpdateTime', 'ReleaseTime', 'Settings', 'Question'])
        data['CreateUser'] = self.CreateUser.id
        return data

    def export(self):
        checkQuestionnaireTime(self)
        # file = self.EncodeID
        # file = "./" + file + ".docx"
        # if os.path.exists(file):
        #    os.remove(file)
        doc = Document()
        p = doc.add_heading(WD_PARAGRAPH_ALIGNMENT.LEFT, level=1)
        p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        r = p.add_run(self.Title)
        p = doc.add_paragraph()
        p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
        p.paragraph_format.space_before = Pt(12)
        p.paragraph_format.space_after = Pt(8)
        r = p.add_run('问卷类型: ' + self.get_Type_display())
        r.font.size = Pt(9)
        r = p.add_run('创建者: '+self.CreateUser.username)
        r.font.size = Pt(9)
        r.add_break()
        r = p.add_run('创建时间: ' + self.CreateTime.strftime('%Y-%m-%d %H:%M:%S'))
        r.font.size = Pt(9)
        r = p.add_run('最近更新时间: ' + self.UpdateTime.strftime('%Y-%m-%d %H:%M:%S'))
        r.font.size = Pt(9)
        if self.ReleaseTime is not None:
            r = p.add_run('最近开启时间: ' + self.ReleaseTime.strftime('%Y-%m-%d %H:%M:%S'))
        r.font.size = Pt(9)
        r.add_break()

        self.Settings.export(doc, self.Type)

        p = doc.add_paragraph()
        p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
        p.paragraph_format.space_before = Pt(8)
        p.paragraph_format.space_after = Pt(18)
        if self.Text:
            r = p.add_run('问卷说明: ' + self.Text)
        r.font.size = Pt(10)
        for q in self.Question.all().order_by('Number'):
            q.export(doc, self.ShowNumber)
        return doc


class Question(models.Model):
    Stem = models.TextField(null=True, blank=True)
    Type = models.IntegerField(choices=((1, '单选题'),
                                        (2, '多选题'),
                                        (3, '填空题'),
                                        (4, '评分题'),
                                        (5, '定位题'),
                                        (6, '投票单选题'),
                                        (7, '投票多选题'),
                                        (8, '报名单选题'),
                                        (9, '报名多选题'),
                                        (10, '考试单选题'),
                                        (11, '考试多选题'),
                                        (12, '考试填空题')), blank=True)
    MaxChoice = models.PositiveIntegerField(default=1, blank=True)
    MinChoice = models.PositiveIntegerField(default=0, blank=True)
    Questionnaire = models.ForeignKey(Questionnaire, blank=True, on_delete=models.CASCADE, related_name='Question')
    Must = models.BooleanField(blank=True, default=False)
    Number = models.PositiveIntegerField(blank=True, null=True)
    Describe = models.TextField(null=True, blank=True)
    Times = models.PositiveIntegerField(null=True, blank=True)
    Score = models.FloatField(blank=True, null=True)
    HalfScore = models.FloatField(blank=True, default=0)
    ShowResultBeforeVote = models.BooleanField(blank=True, default=False)  # 是否在投票前就可查看结果

    def to_dict(self, fields=None, exclude=None):
        data = get_dict(self, fields, exclude)
        data["Answer"] = None
        if self.Type in [1, 6, 8, 10]:
            data["MaxChoice"] = 1
            data["MinChoice"] = 0
        if self.Type == [3, 5, 12]:
            del data["MaxChoice"]
            del data["MinChoice"]
        if self.Type == 4:
            del data["MaxChoice"]
            del data["MinChoice"]
        if self.Type in [1, 2, 4, 6, 7, 8, 9, 10, 11]:
            data["Choice"] = []
            for choice in self.Choice.all():
                data["Choice"].append(choice.to_dict())
        return data

    def to_copy(self):
        data = get_dict(self,  exclude=['id'])
        return data

    def export(self, doc, flag):
        p = doc.add_paragraph()
        p.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
        p.paragraph_format.space_before = Pt(12)
        p.paragraph_format.space_after = Pt(20)
        p.paragraph_format.keep_together = True
        if self.Must:
            r = p.add_run('*')
            r.font.color.rgb = RGBColor(255, 0, 0)
        if flag:
            r = p.add_run(str(self.Number+1)+'. ')
        r = p.add_run(self.Stem)
        string = ''
        if self.Type == 2:
            string = '(多选题,最少选择' + str(self.MinChoice) + '项,最多选择' + str(self.MaxChoice) + '项)'
        elif self.Type == 7:
            string = '(投票多选题,最少选择' + str(self.MinChoice) + '项,最多选择' + str(self.MaxChoice) + '项)'
        elif self.Type == 9:
            string = '(报名多选题,最少选择' + str(self.MinChoice) + '项,最多选择' + str(self.MaxChoice) + '项)'
        elif self.Type == 11:
            string = '(考试多选题,最少选择' + str(self.MinChoice) + '项,最多选择' + str(self.MaxChoice) + '项)'
        else:
            string = '(' + self.get_Type_display() + ')'
        if self.Type in [8, 9] and self.Times is not None:
            string = string + '(限选: ' + str(self.Times) + '次)'
        if self.Type in [10, 12] and self.Score is not None:
            string = string + '(分值: ' + str(round(self.Score, 2)) + '分)'
        if self.Type == 11 and self.Score is not None:
            string = string + '(分值: ' + str(round(self.Score, 2)) + '分, 选对但不全得: ' + str(round(self.HalfScore, 2)) + '分)'
        r = p.add_run(string)
        r.add_break()
        if self.Describe:
            r = p.add_run('注: ' + self.Describe)
            r.font.size = Pt(8)
        r.add_break()
        ch = ord('A')
        if self.Type in [1, 2, 4]:
            for c in self.Choice.all().order_by('id'):
                c.export(p, self.Type, ch)
                ch += 1
        else:
            p.paragraph_format.space_after = Pt(30)


class Choice(models.Model):
    Text = models.TextField(null=True, blank=True)
    Score = models.IntegerField(null=True, blank=True)
    Times = models.IntegerField(null=True, blank=True)
    IsTrueAnswer = models.BooleanField(null=True, blank=True)
    Question = models.ForeignKey(Question, blank=True, on_delete=models.CASCADE, related_name='Choice')

    def to_dict(self, fields=None, exclude=None):
        return get_dict(self, fields, exclude)

    def export(self, p, type, ch):
        p.add_run().add_tab()
        if type in [1, 2, 6, 7, 8, 9, 10, 11]:
            r = p.add_run(chr(ch) + '. ' + self.Text)
            if type in [10, 11] and self.IsTrueAnswer is not None and self.IsTrueAnswer:
                r.font.color.rgb = RGBColor(207, 0, 112)
            if type in [8, 9] and self.Times is not None:
                r = p.add_run('(限选:' + str(self.Times) + '次)')
        else:
            r = p.add_run(str(self.Score) + '分   ' + self.Text)
        r.add_break()
